﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

namespace SocialWebpart
{
    public partial class SocialWebpart
    {
        /// <summary>
        /// TODO: Update summary.
        /// </summary>
        public class FaceBookFeeds
        {
            /// <summary>
            /// Variable to set Face book user id
            /// </summary>
            private string FacebookUserId;

            /// <summary>
            /// Variable to set Face book token id
            /// </summary>
            private string FacebookTokenCode;

            /// <summary>
            /// Variable to set number of face book post to display in the webpart
            /// </summary>
            private int FacebookPostsCount;

            /// <summary>
            /// Setting Webpart properties like User Id, Token Code, post count
            /// </summary>
            /// <param name="facebookUserId">User ID</param>
            /// <param name="facebookTokenCode">Token Code</param>
            /// <param name="facebookPostsCount">Facebook post count</param>
            public FaceBookFeeds(string facebookUserId, string facebookTokenCode, int facebookPostsCount)
            {
                this.FacebookUserId = facebookUserId;
                this.FacebookTokenCode = facebookTokenCode;
                this.FacebookPostsCount = facebookPostsCount;
            }

            /// <summary>
            /// This method returns Face book feed control
            /// </summary>
            /// <returns></returns>
            public WebControl GetFaceBookFeeds()
            {
                //Control for facebook 
                WebControl divFaceBookParent = new WebControl(HtmlTextWriterTag.Div);
                divFaceBookParent.Controls.Add(new Literal()
                {
                    Text = "<div class='tab-content active' id='FaceBook-tab'>"
                });

                string strProfileURL = GetProfileImageURL();
                try
                {
                    Table mainTable = new Table();
                    TableRow tr;
                    TableCell tc;

                    mainTable.Width = Unit.Percentage(100);
                    mainTable.CellSpacing = 0;
                    mainTable.CellPadding = 0;
                    mainTable.CssClass = "webpart-facebook-table-content";


                    if (!string.IsNullOrEmpty(this.FacebookUserId) && !string.IsNullOrEmpty(this.FacebookTokenCode))
                    {
                        RootObj jsonObj = GetFeeds();
                        if (null != jsonObj && jsonObj.data.Count > 0)
                        {
                            int jsonCount = jsonObj.data.Count;
                            bool isValidFeed = false;
                            for (int i = 0; i < jsonCount; i++)
                            {
                                isValidFeed = CheckForProperFeed(jsonObj.data[i]);
                                if (isValidFeed)
                                {
                                    tr = new TableRow();
                                    mainTable.Rows.Add(tr);
                                    tc = new TableCell();
                                    tc.Width = Unit.Percentage(25);
                                    tc.Controls.Add(new LiteralControl("<img src=" + strProfileURL + "></img>"));
                                    tr.Cells.Add(tc);

                                    tc = new TableCell();
                                    tc.CssClass = "post-body";

                                    tc.Controls.Add(FacebookMessageBody(jsonObj.data[i]));
                                    tr.Controls.Add(tc);
                                    mainTable.Rows.Add(tr);
                                }
                            }
                            divFaceBookParent.Controls.Add(mainTable);
                        }
                    }
                }
                catch (Exception e)
                {
                    //Handle exception
                }
                return divFaceBookParent;
            }


            private Table FacebookMessageBody(Data feed)
            {
                Table content = new Table();
                TableRow trContent = new TableRow();
                content.Rows.Add(trContent);
                TableCell tcContent = new TableCell();
                string ctr = "<a href=" + "#" + "><span>" + "Social Webpart" + "</span></a>";
                tcContent.Controls.Add(new LiteralControl(ctr));
                trContent.Controls.Add(tcContent);


                trContent = new TableRow();
                content.Rows.Add(trContent);
                tcContent = new TableCell();
                string message = feed.message.ToSafeString();
                tcContent.Text = ConvertUrlsToLinks(message);
                trContent.Cells.Add(tcContent);

                if (!string.IsNullOrEmpty(feed.picture))
                {
                    trContent = new TableRow();
                    content.Rows.Add(trContent);
                    tcContent = new TableCell();

                    tcContent.Controls.Add(new LiteralControl("<img src=" + feed.picture.ToSafeString() + "></img>"));
                    trContent.Cells.Add(tcContent);
                }

                trContent = new TableRow();
                content.Rows.Add(trContent);
                tcContent = new TableCell();

                tcContent.Text = RelativeTime(feed.created_time.ToSafeString());
                trContent.Controls.Add(tcContent);
                return content;
            }

            /// <summary>
            /// This method will check all dictionary object present or not
            /// </summary>
            /// <param name="feed"></param>
            /// <returns></returns>
            private bool CheckForProperFeed(Data feed)
            {
                if (!string.IsNullOrEmpty(feed.message) && !string.IsNullOrEmpty(feed.created_time))
                {
                    return true;
                }
                return false;
            }

            /// <summary>
            /// Facebook message/post return from api are plain text, we need to convert that to html
            /// </summary>
            /// <param name="message"></param>
            /// <returns></returns>
            private string ConvertUrlsToLinks(string message)
            {
                string strMessage = string.Empty;
                try
                {
                    string regex = @"((www\.|(http|https|ftp|news|file)+\:\/\/)[&#95;.a-z0-9-]+\.[a-z0-9\/&#95;:@=.+?,##%&~-]*[^.|\'|\# |!|\(|?|,| |>|<|;|\)])";
                    Regex regExpression = new Regex(regex, RegexOptions.IgnoreCase);
                    strMessage = regExpression.Replace(message, "<a href=\"$1\" title=\"Click to open in a new window or tab\" target=\"&#95;blank\">$1</a>").Replace("href=\"www", "href=\"http://www");
                }
                catch (Exception ex)
                {
                    //Handle Exception
                }
                return strMessage;
            }

            /// <summary>
            /// This method gets the profile image url for the account
            /// </summary>
            /// <returns></returns>
            private string GetProfileImageURL()
            {
                string imgURL = string.Empty;
                try
                {
                    string FaceBookPageName = "SharepointCommunity";
                    imgURL = string.Format("https://graph.facebook.com/{0}/picture?width=50&height=50", FaceBookPageName);
                    System.Net.HttpWebRequest request = WebRequest.Create(imgURL) as HttpWebRequest;
                    //Bypass the SSL certificate this need to be validated with Saul
                    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

                    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                    {
                        imgURL = response.ResponseUri.ToString();
                    }
                }
                catch (Exception ex)
                {

                }
                return imgURL;
            }

            /// <summary>
            /// This method returns the relative time of facebook post
            /// </summary>
            /// <param name="postTime"></param>
            /// <returns>Returns text to display in the webpart</returns>
            private string RelativeTime(string postTime)
            {
                string strReturn = string.Empty;

                if (!string.IsNullOrEmpty(postTime))
                {
                    DateTime objOriginalTimeStamp = DateTime.Parse(postTime.ToString());
                    DateTime objCurrentDate = DateTime.Now;

                    TimeSpan objTimespan = objCurrentDate.Subtract(objOriginalTimeStamp);

                    if (objTimespan.Days >= 1)
                    {
                        strReturn = String.Format("{0:hh:mm tt MMM dd}" + "th", Convert.ToDateTime(postTime).ToUniversalTime());
                    }
                    else
                    {
                        if (objTimespan.Hours >= 1)
                            strReturn = "about " + objTimespan.Hours + " hours ago";
                        else
                        {
                            if (objTimespan.Minutes >= 1)
                            {
                                strReturn = "about " + objTimespan.Minutes + " minutes ago";
                            }
                            else
                                strReturn = "about " + objTimespan.Seconds + " seconds ago";
                        }
                    }
                }
                return strReturn;
            }

            /// <summary>
            /// This method used to get the feeds from face book api
            /// </summary>
            /// <returns>Returns JSON object</returns>
            private RootObj GetFeeds()
            {
                RootObj objJsonObject = null;
                string strAccessurl;
                System.Net.HttpWebRequest objWebRequest;
                string oAuthToken = string.Empty;

                try
                {
                    var client = new WebClient();
                    string oauthUrl = string.Format("https://graph.facebook.com/oauth/access_token?type=client_cred&client_id={0}&client_secret={1}", this.FacebookUserId, this.FacebookTokenCode);

                    //Bypass the SSL certificate this need to be validated with Saul
                    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

                    string accessToken = client.DownloadString(oauthUrl).Split('=')[1];
                    string FacebookPageName = "socialwebpart";
                    strAccessurl = string.Format("https://graph.facebook.com/{0}/posts?access_token={1}", FacebookPageName, accessToken);
                    objWebRequest = WebRequest.Create(strAccessurl) as HttpWebRequest;
                    using (HttpWebResponse objResponse = objWebRequest.GetResponse() as HttpWebResponse)
                    {
                        StreamReader reader = new StreamReader(objResponse.GetResponseStream());
                        string strVal = reader.ReadToEnd();

                        objJsonObject = JSONForFaceBook.CreateFromString(strVal);
                    }
                }
                catch (Exception Ex)
                {
                }
                return objJsonObject;
            }
        }
    }

    public static class StringExtension
    {
        public static string ToSafeString(this String str)
        {
            return string.IsNullOrEmpty(str) ? string.Empty : str;
        }
    }
}